#include "ASTableBar.h"

static as_ret as_ctrl_tablebar_change_focus_idx(as_control* ctrl_p, ASINT idx)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT i = 0;

    if(!ctrl_p)
    {
        return AS_INVALID_PARAM;
    }

    if(idx == tb_p->focus_idx || idx >= tb_p->cur_item_counts)
    {
        return AS_IGNORE;
    }

    tb_p->focus_idx = idx;
    as_disable_flush();

    for(i = 0; i < tb_p->cur_item_counts; i++)
    {
        if(i == tb_p->focus_idx)
        {
            tb_p->items[i]->change_status((as_control*)tb_p->items[i], AS_BUTTON_DOWN);
        }
        else
        {
            tb_p->items[i]->change_status((as_control*)tb_p->items[i], AS_BUTTON_UP);
        }

#if defined(AS_RUN_ON_SKY)
        as_reset_clip();
        as_set_layer_clip_ex(i, &tb_p->base.area);
#endif
    }

    if(tb_p->focus_bg_img)
    {
        tb_p->focus_bg_img->base.change_area_hdlr((as_control*)tb_p->focus_bg_img, tb_p->items[tb_p->focus_idx]->base.area);
    }

    as_enable_flush();
    tb_p->base.paint_hdlr((as_control*)tb_p);
    as_ctrl_flush();

    //callback
    if(tb_p->callback)
    {
        tb_p->callback(tb_p->focus_idx);
    }

    return AS_OK;
}

static as_ret as_ctrl_tablebar_change_to_next(as_control* ctrl_p)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT idx;

    if(!tb_p)
        return AS_INVALID_PARAM;

    idx = tb_p->focus_idx + 1;

    if(idx >= tb_p->cur_item_counts)
        idx = 0;

    tb_p->change_focus_idx((as_control*)tb_p, idx);
    return AS_OK;
}

static as_ret as_ctrl_tablebar_change_to_prev(as_control* ctrl_p)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT idx;

    if(!tb_p)
        return AS_INVALID_PARAM;

    idx = tb_p->focus_idx - 1;

    if(idx < 0)
        idx = tb_p->cur_item_counts - 1;

    tb_p->change_focus_idx((as_control*)tb_p, idx);
    return AS_OK;
}

static as_ret as_ctrl_tablebar_set_show_type(as_control* ctrl_p, as_tablebar_show_type show_type)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || tb_p->show_type == show_type)
        return AS_INVALID_PARAM;

    tb_p->show_type = show_type;
    return AS_OK;
}

static as_button* as_ctrl_tablebar_add_item(as_control* ctrl_p, ASWSTR param1, ASWSTR param2, ASWSTR param3, ASUINT img_src_type)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    as_button* btn_p;
    as_rect area;
    as_rect* base_rect_p = &tb_p->base.area;

    if(!ctrl_p || tb_p->cur_item_counts >= tb_p->max_item_counts || param1 == ASNULL || as_wstrlen(param1) <= 0)
        return ASNULL;

    if(tb_p->type == AS_TABLEBAR_IMAGE_TYPE && (param2 == ASNULL || as_wstrlen(param2) <= 0))
        return ASNULL;

    if(tb_p->show_type == AS_TABLEBAR_SHOW_HORIZONTAL)
    {
        area.x = (ASINT16)(base_rect_p->x + tb_p->cur_item_counts * tb_p->item_w);
        area.y = base_rect_p->y;
        area.w = (ASUINT16)tb_p->item_w;
        area.h = base_rect_p->h;
    }
    else //if(tb_p->show_type == AS_TABLEBAR_SHOW_VERTICAL)
    {
        area.y = (ASINT16)(base_rect_p->y + tb_p->cur_item_counts * tb_p->item_h);
        area.x = base_rect_p->x;
        area.h = (ASUINT16)tb_p->item_h;
        area.w = base_rect_p->w;
    }

    if(tb_p->type == AS_TABLEBAR_TEXT_TYPE)
    {
        btn_p = as_ctrl_button_create(area, AS_TEXT_BUTTON, param1, ASNULL, ASNULL, ASNULL);
    }
    else //if(tb_p->type == AS_TABLEBAR_IMAGE_TYPE)
    {
        btn_p = as_ctrl_button_create(area, AS_IMAGE_BUTTON, param1, param2, param3, img_src_type);
    }

    if(!btn_p)
        return ASNULL;

    tb_p->items[tb_p->cur_item_counts] = btn_p;
    tb_p->cur_item_counts++;
    return btn_p;
}

static as_button* as_ctrl_tablebar_get_item(as_control* ctrl_p, ASINT idx)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || idx < 0 || idx >= tb_p->cur_item_counts)
        return ASNULL;

    return tb_p->items[idx];
}

static as_ret as_ctrl_tablebar_set_bg_color(as_control* ctrl_p, ASUINT color)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || tb_p->bg_color == color)
        return AS_INVALID_PARAM;

    tb_p->bg_color = color;
    return AS_OK;
}

static as_ret as_ctrl_tablebar_set_focus_bg_color(as_control* ctrl_p, ASUINT color)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || tb_p->focus_bg_color == color)
        return AS_INVALID_PARAM;

    tb_p->focus_bg_color = color;
    return AS_OK;
}

static as_ret as_ctrl_tablebar_set_bg_img(as_control* ctrl_p, as_image_src_type type, ASWSTR path)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    as_rect* area_p;

    if(!tb_p || !path)
        return AS_INVALID_PARAM;

    if(tb_p->bg_img)
    {
        as_ctrl_image_destroy(tb_p->bg_img);
    }

    area_p = &tb_p->base.area;
    tb_p->bg_img = as_ctrl_image_create(*area_p, type, path, FALSE);

    if(tb_p->bg_img)
    {
        tb_p->bg_img->set_show_type((as_control*)tb_p->bg_img, AS_IMAGE_TILED);
        return AS_OK;
    }

    return AS_MEMORY_NOT_ENOUGH;
}

static as_ret as_ctrl_tablebar_set_focus_bg_img(as_control* ctrl_p, as_image_src_type type, ASWSTR path)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    as_rect* area_p;

    if(!tb_p || !path)
        return AS_INVALID_PARAM;

    if(tb_p->focus_bg_img)
    {
        as_ctrl_image_destroy(tb_p->focus_bg_img);
    }

    if(tb_p->focus_idx >= 0)
    {
        area_p = &tb_p->items[tb_p->focus_idx]->base.area;
    }
    else
    {
        area_p = &tb_p->base.area;
    }

    tb_p->focus_bg_img = as_ctrl_image_create(*area_p, type, path, FALSE);

    if(tb_p->focus_bg_img)
        return AS_OK;

    return AS_MEMORY_NOT_ENOUGH;
}

static as_ret as_ctrl_tablebar_set_focus_bg_offset(as_control* ctrl_p, ASINT x_off, ASINT y_off)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || !tb_p->focus_bg_img)
        return AS_INVALID_PARAM;

    tb_p->focus_bg_img->set_show_type((as_control*)tb_p->focus_bg_img, AS_IMAGE_CUSTOM);
    tb_p->focus_bg_img->set_show_offset((as_control*)tb_p->focus_bg_img, x_off, y_off);
    return AS_OK;
}


static void as_ctrl_tablebar_paint(as_control* ctrl_p)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    as_rect* area_p;
    ASINT i = 0, layer;

    if(!tb_p || ctrl_p->if_hidden)
        return;

    area_p = &tb_p->base.area;
    layer = ctrl_p->show_hdlr;

    if(layer < 0 || as_set_layer_clip_ex(layer, area_p) == AS_IGNORE)
        return;

    //draw bg
    if(tb_p->bg_img)
    {
        tb_p->bg_img->base.paint_hdlr((as_control*)tb_p->bg_img);
    }
    else
    {
        as_fill_rect(area_p, tb_p->bg_color, tb_p->bg_color);
    }

    //draw focus bg
    if(tb_p->focus_bg_img)
    {
        tb_p->focus_bg_img->base.paint_hdlr((as_control*)tb_p->focus_bg_img);
    }
    else
    {
        if(tb_p->focus_idx >= 0)
            as_fill_rect(&(tb_p->items[tb_p->focus_idx]->base.area), tb_p->focus_bg_color, tb_p->focus_bg_color);
    }

    for(i = 0; i < tb_p->cur_item_counts; i++)
    {
        if(tb_p->items[i])
            tb_p->items[i]->base.paint_hdlr((as_control*)tb_p->items[i]);

#if defined(AS_RUN_ON_SKY)
        as_reset_clip();
        as_set_layer_clip_ex(layer, area_p);
#endif
    }

    as_reset_layer_clip(layer);
}

static as_ret as_ctrl_tablebar_key_hdlr(as_control* ctrl_p, ASINT event, ASINT keycode)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT prev_key, next_key;

    if(!tb_p || ctrl_p->if_hidden)
        return AS_INVALID_PARAM;

    if(tb_p->show_type == AS_TABLEBAR_SHOW_HORIZONTAL)
    {
        prev_key = AS_KEY_LEFT;
        next_key = AS_KEY_RIGHT;
    }
    else //if(tb_p->show_type == AS_TABLEBAR_SHOW_VERTICAL)
    {
        prev_key = AS_KEY_UP;
        next_key = AS_KEY_DOWN;
    }

    if(keycode == prev_key && event == AS_EVT_KEY_UP)
    {
        return tb_p->change_to_prev((as_control*)tb_p);
    }
    else if(keycode == next_key && event == AS_EVT_KEY_UP)
    {
        return tb_p->change_to_next((as_control*)tb_p);
    }
    else
    {
        return AS_IGNORE;
    }
}

static as_ret as_ctrl_tablebar_set_cb(as_control* ctrl_p, table_cb cb)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || !cb)
        return AS_INVALID_PARAM;

    tb_p->callback = cb;
    return AS_OK;
}

static as_ret as_ctrl_tablebar_set_item_cb(as_control* ctrl_p, table_item_cb cb)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;

    if(!tb_p || !cb)
        return AS_INVALID_PARAM;

    tb_p->item_callback = cb;
    return AS_OK;
}


static as_ret as_ctrl_tablebar_pen_hdlr(as_control* ctrl_p, ASINT event, ASINT x, ASINT y)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT i = 0;

    if(!tb_p || ctrl_p->if_hidden)
    {
        return AS_INVALID_PARAM;
    }

    for(i = 0; i < tb_p->cur_item_counts; i++)
    {
        if(AS_POINT_IN_RECT(x, y, tb_p->items[i]->base.area))
        {
            break;
        }
    }

    if(i == tb_p->cur_item_counts)
    {
        return AS_IGNORE;
    }

    if(event == AS_EVT_TOUCH_DOWN)
    {
        return tb_p->change_focus_idx((as_control*)tb_p, i);
    }
    else if(event == AS_EVT_TOUCH_UP)
    {
        if(i == tb_p->focus_idx && tb_p->item_callback)
        {
            tb_p->item_callback();
            return AS_OK;
        }
        else
            return AS_IGNORE;
    }
    else
    {
        return AS_IGNORE;
    }
}

static void as_ctrl_tablebar_move(as_control* ctrl_p, ASINT x_off, ASINT y_off)
{
    as_tablebar* tb_p = (as_tablebar*)ctrl_p;
    ASINT i = 0;

    if(!tb_p)
        return;

    tb_p->base.area.x += (ASINT16)x_off;
    tb_p->base.area.y += (ASINT16)y_off;

    for(i = 0; i < tb_p->cur_item_counts; i++)
    {
        if(tb_p->items[i])
            tb_p->items[i]->base.move((as_control*)tb_p->items[i], x_off, y_off);
    }
}

as_tablebar* as_ctrl_tablebar_create(as_rect area, ASINT item_count, as_tablebar_src_type type, as_tablebar_show_type show_type)
{
    as_tablebar* tb_p = ASNULL;

    if(item_count < 1 || item_count > AS_TABLEBAR_MAX_ITEMS)
    {
        return tb_p;
    }

    tb_p = as_calloc(sizeof(as_tablebar));

    if(!tb_p)
    {
        return tb_p;
    }

    as_ctrl_init((as_control*)tb_p, area);
    tb_p->base.paint_hdlr = as_ctrl_tablebar_paint;
    tb_p->base.pen_hdlr = as_ctrl_tablebar_pen_hdlr;
    tb_p->base.key_hdlr = as_ctrl_tablebar_key_hdlr;
    tb_p->base.move = as_ctrl_tablebar_move;
    tb_p->base.ctrl_type = AS_CTRL_TABLEBAR;
    tb_p->focus_idx = -1;
    tb_p->cur_item_counts = 0;
    tb_p->max_item_counts = item_count;
    tb_p->type = type;
    tb_p->show_type = show_type;

    if(tb_p->show_type == AS_TABLEBAR_SHOW_HORIZONTAL)
    {
        tb_p->item_h = tb_p->base.area.h;
        tb_p->item_w = tb_p->base.area.w / tb_p->max_item_counts;
    }
    else //if(tb_p->show_type == AS_TABLEBAR_SHOW_VERTICAL)
    {
        tb_p->item_w = tb_p->base.area.w;
        tb_p->item_h = tb_p->base.area.h / tb_p->max_item_counts;
    }

    tb_p->add_item = as_ctrl_tablebar_add_item;
    tb_p->get_item = as_ctrl_tablebar_get_item;
    tb_p->change_focus_idx = as_ctrl_tablebar_change_focus_idx;
    tb_p->set_bg_color = as_ctrl_tablebar_set_bg_color;
    tb_p->set_bg_img = as_ctrl_tablebar_set_bg_img;
    tb_p->set_focus_bg_img = as_ctrl_tablebar_set_focus_bg_img;
    tb_p->set_focus_bg_color = as_ctrl_tablebar_set_focus_bg_color;
    tb_p->set_focus_bg_offset = as_ctrl_tablebar_set_focus_bg_offset;
    tb_p->change_to_next = as_ctrl_tablebar_change_to_next;
    tb_p->change_to_prev = as_ctrl_tablebar_change_to_prev;
    tb_p->set_show_type = as_ctrl_tablebar_set_show_type;
    tb_p->set_cb = as_ctrl_tablebar_set_cb;
    tb_p->set_item_cb = as_ctrl_tablebar_set_item_cb;
    return tb_p;
}


as_ret as_ctrl_tablebar_destroy(as_tablebar* ctrl_tablebar_p)
{
    as_ret ret = AS_OK;
    ASINT i = 0;

    if(!ctrl_tablebar_p)
    {
        ret = AS_INVALID_PARAM;
        return ret;
    }

    if(ctrl_tablebar_p->bg_img)
    {
        as_ctrl_image_destroy(ctrl_tablebar_p->bg_img);
        ctrl_tablebar_p->bg_img = ASNULL;
    }

    if(ctrl_tablebar_p->focus_bg_img)
    {
        as_ctrl_image_destroy(ctrl_tablebar_p->focus_bg_img);
        ctrl_tablebar_p->focus_bg_img = ASNULL;
    }

    for(i = 0; i < ARRAY_SIZE(ctrl_tablebar_p->items); i++)
    {
        if(ctrl_tablebar_p->items[i])
        {
            as_ctrl_button_destroy(ctrl_tablebar_p->items[i]);
            ctrl_tablebar_p->items[i] = ASNULL;
        }
    }

    as_free(ctrl_tablebar_p);
    ctrl_tablebar_p = ASNULL;
    return ret;
}